import Darwin

// 实现Equatable协议,可以比较自定义类型是否相等
// 实现Comparable协议,可以比较 > < >= <=
// 因为 Comparable 继承自 Equatable,所以,集成了子类就相当与继承了父类
struct Point: Comparable {
    let x: Int
    let y: Int

    static func == (l: Point, r: Point) -> Bool {
        return (l.x == r.x) && (r.y == r.y)
    }

    static func < (lhs: Point, rhs: Point) -> Bool {
        let lDistance = (lhs.x - 0) * (lhs.x - 0) + (lhs.y - 0) * (lhs.y - 0)
        let rDistance = (rhs.x - 0) * (rhs.x - 0) + (rhs.y - 0) * (rhs.y - 0)

        let l = sqrt(Double(lDistance))
        let r = sqrt(Double(rDistance))

        return l < r
    }

    static func + (lhs: Point, rhs: Point) -> Point {
        return Point(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
    }
}

let a = Point(x: 3, y: 4)
let b = Point(x: 3, y: 4)

print(a == b)
// 如果符合了Equatable协议,并且实现了 == 方法
// 那么也就有了一个可用的 != 方法
print(a != b)

let c = Point(x: 4, y: 16)
let d = Point(x: 3, y: 7)
print("c是否小于d \(c < d)")

print("c是否小于等于d \(c <= d)")
print("c是否大于d \(c > d)")
print("c是否大于等于d \(c >= d)")

let e = c + d
print("e \(e)")

// 练习:
class Person: CustomStringConvertible, Equatable {
    static func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.name == rhs.name && lhs.age == rhs.age
    }

    var name: String
    var age: Int
    weak var spouse: Person?

    init(name: String, age: Int, spouse: Person? = nil) {
        self.name = name
        self.age = age
        self.spouse = spouse
    }

    var description: String {
        return "name:\(name) age:\(age)"
    }
}

let p1 = Person(name: "小明", age: 12)
let p2 = Person(name: "小红", age: 13)

let people = [p1, p2]
print(people)

people.firstIndex(of: p2)

// 定义一个中缀运算符,必须在全局作用域声明
infix operator +++

//实现自定义运算符
func +++ (lhs: Person, rhs: Person) {
    lhs.spouse = rhs
    rhs.spouse = lhs
}

p1 +++ p2
print("p1的配偶:\(p1.spouse)")
print("p2的配偶:\(p2.spouse)")

//一般避免自定义运算符,因为比较难懂,还是使用方法来实现相应功能更好
